package com.spzx.cart.service.impl;

import com.spzx.cart.domain.CartInfo;
import com.spzx.cart.service.ICartService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.context.SecurityContextHolder;
import com.spzx.common.core.domain.R;
import com.spzx.common.security.utils.SecurityUtils;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.domain.ProductSku;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.security.Security;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static org.bouncycastle.asn1.x500.style.RFC4519Style.*;

@Service
public class ICartServiceImpl implements ICartService {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RemoteProductService remoteProductService;


    //添加商品到购物车
    @Override
    public void getAddToCart(Long skuId, Integer skuNum) {
        //最终是要加到redis 的hash类型中去
        //获取用户id，只有登录时才可以添加购物车
        Long userId = SecurityUtils.getUserId();
        //2 根据用户id，获取购物车所有的skuid和对应的sku信息
        String key = "cart:data:" + userId;
//        Object o = redisTemplate.opsForHash().get(key, skuId);
        BoundHashOperations<String, String, CartInfo> boundHashOperations =
                redisTemplate.boundHashOps(key);
        // 3  判断用户购物车数据是否包含当前添加skuid，
        String hashKey = skuId.toString();
        if (boundHashOperations.hasKey(hashKey)) {
            // 如果包含，表示商品已经在购物车里，只需把数量获取出来+1，放回到购物车里
//                CartInfo cartInfo = (CartInfo) redisTemplate.opsForHash().get(hashKey, skuId);
            CartInfo cartInfo = boundHashOperations.get(hashKey);
            int skuNum1 = cartInfo.getSkuNum()+skuNum;
            cartInfo.setSkuNum(skuNum1);
            boundHashOperations.put(hashKey, cartInfo);
        }else{
            //如果不包含，直接添加
            CartInfo cartInfo = new CartInfo();
            cartInfo.setUserId(userId);
            cartInfo.setSkuNum(skuNum);
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());
            //远程调用，根据skuid获取sku信息
            R<ProductSku> productSkuR = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
            ProductSku productSku = productSkuR.getData();
            cartInfo.setSkuId(skuId);
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setCartPrice(productSku.getSalePrice());
            cartInfo.setSkuPrice(productSku.getSalePrice());
            cartInfo.setThumbImg(productSku.getThumbImg());
//        redisTemplate.opsForHash().put(userId,skuId,cartInfo);
            //放到hash类型里面
            boundHashOperations.put(hashKey, cartInfo);
        }
    }

    //显示购物车列表
    @Override
    public List<CartInfo> getCartList() {
        //获取登录用户id
        Long userId = SecurityUtils.getUserId();
        String key = "cart:data:" + userId;
        //根据key获取所有的cartInfo信息
        List<CartInfo> cartInfoList = redisTemplate.opsForHash().values(key);
        //按照时间顺序排序
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            List<CartInfo> infoList = cartInfoList.stream().sorted(
                    (o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime())
            ).collect(Collectors.toList());
            return infoList;
        }
        //为空，就返回一个新集合
        //方便前端渲染，传一个没有元素的集合，前端会渲染一个没有列表项的页面
        return new ArrayList<>();
    }

    //删除购物车商品
    @Override
    public void deleteCart(Long skuId) {
        Long userId = SecurityUtils.getUserId();
        String key = "cart:data:" + userId;

        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(key);
        boundHashOperations.delete(skuId.toString());

    }

    //更新选中状态
    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        Long userId = SecurityContextHolder.getUserId();
//        Long userId = SecurityUtils.getUserId();
        String key = "cart:data:" + userId;
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(key);
        if(boundHashOperations.hasKey(skuId.toString())){
            CartInfo cartInfo = boundHashOperations.get(skuId.toString());
            cartInfo.setIsChecked(isChecked);

            boundHashOperations.put(skuId.toString(),cartInfo);
        }
    }

    //全选全不选
    @Override
    public void getAllCart(Integer isChecked) {
        //获取用户登录id
        Long userId = SecurityContextHolder.getUserId();
        String key = "cart:data:"+userId;

        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(key);
        List<CartInfo> cartInfoList = boundHashOperations.values();
        cartInfoList.forEach(
                (item)->{
                    CartInfo cartInfoUpd = boundHashOperations.get(item.getSkuId().toString());
                    cartInfoUpd.setIsChecked(isChecked);
                    boundHashOperations.put(item.getSkuId().toString(),cartInfoUpd);
                }
        );

    }

    //清空购物车
    @Override
    public void deleteAllCart() {
        //获取用户登录id
        Long userId = SecurityContextHolder.getUserId();
        String key = "cart:data:"+userId;

//        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(key);
//        boundHashOperations.delete(key);
        redisTemplate.delete(key);

    }

    //远程调用接口：获取选中的购物车列表
    @Override
    public List<CartInfo> getCartCheckedList() {
        //获取登录用户的id
        Long userId = SecurityUtils.getUserId();
        String key = "cart:data:"+userId;
        //创建一个新的集合list，用于存放最终数据
        List<CartInfo> list  = new ArrayList<>();
        //根据key(userId) 获取redis里面hash类型的所有value值
        List<CartInfo> cartInfoList = redisTemplate.opsForHash().values(key);
        //根据获取所有value值list集合，遍历，得到每个cartinfo对象，判断是否选中
        cartInfoList.forEach((cartInfo)->{
            if(cartInfo.getIsChecked().intValue()==1){
                list.add(cartInfo);
            }
        });
        return list;
    }
}
